package com.common.app.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.Path
import android.graphics.RectF
import android.graphics.Shader
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import com.common.app.R

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：2024/11/14
 *
 * 描述：
 *
 * 修订历史：
 *
 */
class FourColorProgressBar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private var progress = 0f
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private lateinit var gradient: LinearGradient
    private lateinit var borderGradient: LinearGradient

    // 可配置参数
    private var borderMargin = 2f.dpToPx() // 外环边距
    private var borderWidth = 3f.dpToPx()  // 外环宽度

    // 预先分配对象
    private val progressClipPath = Path()
    private val progressRectF = RectF()
    private val borderRectF = RectF()
    private val backgroundRectF = RectF()

    private var colors = intArrayOf(
        Color.parseColor("#FF0000"),
        Color.parseColor("#00FF00"),
        Color.parseColor("#0000FF"),
        Color.parseColor("#FFFF00")
    )

    init {
        // 读取自定义属性
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.cus_fourColorProgressBar,
            0, 0
        ).apply {
            try {
                borderMargin = getDimension(
                    R.styleable.cus_fourColorProgressBar_cus_fcpb_borderMargin,
                    borderMargin
                )
                borderWidth = getDimension(
                    R.styleable.cus_fourColorProgressBar_cus_fcpb_borderWidth,
                    borderWidth
                )
                backgroundPaint.color = getColor(
                    R.styleable.cus_fourColorProgressBar_cus_fcpb_backgroundColor,
                    Color.LTGRAY
                )

                // 读取自定义颜色
                colors[0] = getColor(R.styleable.cus_fourColorProgressBar_cus_fcpb_color1, colors[0])
                colors[1] = getColor(R.styleable.cus_fourColorProgressBar_cus_fcpb_color2, colors[1])
                colors[2] = getColor(R.styleable.cus_fourColorProgressBar_cus_fcpb_color3, colors[2])
                colors[3] = getColor(R.styleable.cus_fourColorProgressBar_cus_fcpb_color4, colors[3])
            } finally {
                recycle()
            }
        }

        backgroundPaint.style = Paint.Style.FILL
        borderPaint.style = Paint.Style.STROKE
        borderPaint.strokeWidth = borderWidth
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        // 外环矩形
        borderRectF.set(
            borderWidth / 2f,
            borderWidth / 2f,
            width - borderWidth / 2f,
            height - borderWidth / 2f
        )

        // 内容区域矩形（背景和进度条使用）
        val contentLeft = borderWidth + borderMargin
        val contentTop = borderWidth + borderMargin
        val contentRight = width - (borderWidth + borderMargin)
        val contentBottom = height - (borderWidth + borderMargin)

        backgroundRectF.set(contentLeft, contentTop, contentRight, contentBottom)

        updateGradients()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        val radius = height / 2f
        val contentRadius = radius - (borderWidth + borderMargin)

        // 绘制背景
        canvas.drawRoundRect(
            backgroundRectF,
            contentRadius,
            contentRadius,
            backgroundPaint
        )

        // 计算进度宽度
        val progressWidth = (width - 2 * (borderWidth + borderMargin)) * (progress / 100f)

        // 当进度宽度大于0时才绘制进度
        if (progressWidth > 0) {
            // 设置进度条矩形
            progressRectF.set(
                backgroundRectF.left,
                backgroundRectF.top,
                backgroundRectF.left + progressWidth,
                backgroundRectF.bottom
            )

            // 重置并设置裁剪路径
            progressClipPath.reset()
            progressClipPath.addRoundRect(
                progressRectF,
                contentRadius,
                contentRadius,
                Path.Direction.CW
            )

            // 保存画布状态
            canvas.save()
            canvas.clipPath(progressClipPath)
            canvas.drawRoundRect(
                backgroundRectF,
                contentRadius,
                contentRadius,
                paint
            )
            canvas.restore()
        }

        // 绘制外环
        canvas.drawRoundRect(
            borderRectF,
            radius,
            radius,
            borderPaint
        )
    }

    // 根据颜色数量计算位置数组
    private fun calculatePositions(): FloatArray {
        return FloatArray(colors.size) { index ->
            index.toFloat() / (colors.size - 1)
        }
    }

    // 更新渐变
    private fun updateGradients() {// 更新矩形范围
        val positions = calculatePositions()
        gradient = LinearGradient(
            0f, 0f, width.toFloat(), 0f,
            colors,
            positions,
            Shader.TileMode.CLAMP
        )
        paint.shader = gradient

        borderGradient = LinearGradient(
            0f, 0f, width.toFloat(), 0f,
            colors,
            positions,
            Shader.TileMode.CLAMP
        )
        borderPaint.shader = borderGradient
    }

    // 添加设置颜色的方法
    fun setColors(vararg newColors: Int) {
        require(newColors.isNotEmpty()) { "At least one color must be provided" }
        colors = newColors
        updateGradients()
        invalidate()
    }

    fun setProgress(value: Float) {
        progress = value.coerceIn(0f, 100f)
        invalidate()
    }

    // dp转px的扩展函数
    private fun Float.dpToPx(): Float {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            this,
            resources.displayMetrics
        )
    }

    // 设置外环边距
    fun setBorderMargin(dpValue: Float) {
        borderMargin = dpValue.dpToPx()
        invalidate()
    }

    // 设置外环宽度
    fun setBorderWidth(dpValue: Float) {
        borderWidth = dpValue.dpToPx()
        borderPaint.strokeWidth = borderWidth
        invalidate()
    }
}